package cn.enilu.flash.api.controller.h5;

import cn.enilu.flash.bean.dto.ProofDto;
import cn.enilu.flash.bean.dto.SubmitOrderProofDto;
import cn.enilu.flash.bean.entity.order.TaskOrder;
import cn.enilu.flash.bean.entity.system.User;
import cn.enilu.flash.bean.entity.task.HelpTask;
import cn.enilu.flash.bean.entity.task.Proof;
import cn.enilu.flash.bean.vo.front.Ret;
import cn.enilu.flash.bean.vo.front.Rets;
import cn.enilu.flash.bean.vo.query.SearchFilter;
import cn.enilu.flash.bean.vo.task.*;
import cn.enilu.flash.security.JwtUtil;
import cn.enilu.flash.service.order.TaskOrderService;
import cn.enilu.flash.service.system.UserService;
import cn.enilu.flash.service.task.HelpTaskService;
import cn.enilu.flash.service.task.MoneyInfoService;
import cn.enilu.flash.service.task.ProofService;
import cn.enilu.flash.utils.DateUtil;
import cn.enilu.flash.utils.StringUtil;
import io.swagger.annotations.Api;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/h5/taskOrder")
@Transactional
@Api(tags = "订单相关接口")
public class H5TaskOrderController {
    @Value("${auditFailed}")
    private Integer auditFailed; // 审核失败自动放弃基础时间（小时）
    @Value("${auditTimeLimit}")
    private Integer auditTimeLimit; // 用户提交凭证后，若发布人不审核自动通过基础时间（小时）
    @Autowired
    private TaskOrderService orderService;

    @Autowired
    private HelpTaskService taskService;

    @Autowired
    private UserService userService;

    @Autowired
    private ProofService proofService;

    @Autowired
    private MoneyInfoService moneyInfoService;

    /**
     * 用户接单
     * @param taskId 任务id
     * @return
     */
    @GetMapping("/add")
    public Ret add(Long taskId){
        User user = userService.get(JwtUtil.getUserId());
        if(StringUtil.isNullOrEmpty(taskId)){
            return Rets.failure("任务ID不能为空！");
        }
        HelpTask helpTask = taskService.get(taskId);
        if(StringUtil.isNullOrEmpty(helpTask)){
            return Rets.failure("任务不存在！");
        }
        if(helpTask.getState()!=1){
            return Rets.failure("任务不是进行中的任务！");
        }
        if(helpTask.getLastNum()<1){
            helpTask.setState(6); // 暂停任务
            taskService.update(helpTask);
            return Rets.failure("该任务已被抢完啦");
        }
        if(helpTask.getCreateBy() == user.getId()){
            return Rets.failure("不能接自己发布的任务哦");
        }
        long count = orderService.count(SearchFilter.build("state",1));
        if(count>0) return Rets.failure("该任务还有未提交的订单~");
        helpTask.setLastNum(helpTask.getLastNum()-1); // 扣数量
        if(helpTask.getLastNum() == 0) helpTask.setState(6);
        taskService.update(helpTask);// 先保存扣除数量
        TaskOrder taskOrder = new TaskOrder();
        taskOrder.setCreateBy(user.getId());
        taskOrder.setCreateTime(new Date());
        taskOrder.setTaskId(taskId);
        taskOrder.setIssuerId(helpTask.getCreateBy());
        taskOrder.setState(1);
        taskOrder.setTaskTitle(helpTask.getTitle());
        taskOrder.setTimeLimit(DateUtil.getAfterHourDate(helpTask.getTimeLimit()));
        taskOrder.setMoney(helpTask.getPrice());
        taskOrder = orderService.insert(taskOrder);
        if(StringUtil.isNullOrEmpty(taskOrder)){
            throw new RuntimeException("新增任务订单失败！");
        }
        List<Proof> taskProofs = proofService.queryAll(new SearchFilter("taskId", SearchFilter.Operator.EQ,taskId));
        for(Proof proof:taskProofs){
            Proof newproof = new Proof();
            String[] str = {"id","createBy","createTime","taskId"};
            BeanUtils.copyProperties(proof, newproof, str);
            newproof.setCreateBy(JwtUtil.getUserId());
            newproof.setOrderId(taskOrder.getId());
            /*proof.setCreateTime(taskOrder.getCreateTime());
            proof.setTaskId(null);
            */
            proof = proofService.insert(newproof);
            if(StringUtil.isNullOrEmpty(proof)) throw new RuntimeException("保存凭证列表失败！");
        }//
        return Rets.success(taskOrder.getId());
    }
    /**
    * 查看订单详情
    * @param orderId:
    */
    @GetMapping("/getOrderDetail")
    public Ret getOrderDetail(Long orderId){
        if(orderId == null){
            return Rets.failure("订单不存在！");
        }
        TaskOrder taskOrder = orderService.get(orderId);
        if(taskOrder == null){
            return Rets.failure("订单不存在！");
        }
        if(taskOrder.getIssuerId()!=JwtUtil.getUserId() && taskOrder.getCreateBy()!=JwtUtil.getUserId()){
            return Rets.failure("只能查看属于自己的订单哦！");
        }
        List<Proof> proofList = proofService.queryAll(new SearchFilter("orderId", SearchFilter.Operator.EQ, orderId));
        HelpTask helpTask = taskService.get(taskOrder.getTaskId());
        List<ProofDto> proofDtos = new ArrayList<>();
        for(Proof proof:proofList){
            ProofDto orderProofDto = new ProofDto();
            BeanUtils.copyProperties(proof,orderProofDto);
            proofDtos.add(orderProofDto);
        }
        if(taskOrder.getCreateBy() == JwtUtil.getUserId()){// 接单人查看订单
            OrderUserDetailVo userDetailVo = new OrderUserDetailVo();
            BeanUtils.copyProperties(taskOrder,userDetailVo);
            userDetailVo.setSketch(helpTask.getSketch());
            userDetailVo.setProofDtoList(proofDtos);
            return Rets.success(userDetailVo);
        }else {
            OrderIssuerDetailVo issuerDetailVo = new OrderIssuerDetailVo();
            BeanUtils.copyProperties(taskOrder,issuerDetailVo);
            issuerDetailVo.setSketch(helpTask.getSketch());
            issuerDetailVo.setProofDtoList(proofDtos);
            return Rets.success(issuerDetailVo);
        }
    }
    /**
     * 我的审核
    * @param result: 审核结果：-1全部, 0未审核，1通过，2不通过，3被申诉，4未提交
    * @param page:
    * @param limit:
    */
    @GetMapping("/myAudit")
    public Ret myAudit(@RequestParam(defaultValue = "-1") Integer result,
                       @RequestParam(defaultValue = "-1") Integer taskId,
                       @RequestParam(defaultValue = "1") Integer page,
                       @RequestParam(defaultValue = "10") Integer limit){
        StringBuffer sql = new StringBuffer("select * from t_task_order where 1=1");
        sql.append(" and issuer_id = "+JwtUtil.getUserId());
        sql.append(" and state not in(6)");
        if(taskId!=-1){
            sql.append(" and task_id = " + taskId);
        }
        if(result == 0){
            sql.append(" and state = 2");
        }
        if(result == 1){
            sql.append(" and result in(1,3)");
        }
        if(result == 2){
            sql.append(" and result = 2");
        }
        if(result == 3){
            sql.append(" and state = 5");
        }
        if(result == 4){
            sql.append(" and state = 1");
        }
        if(page<1) page = 1;
        int start = (page-1)*limit;
        sql.append(" LIMIT "+start+","+limit);
        List<TaskOrder> taskOrders = orderService.queryBySql(sql.toString());
        List<MyAuditListVo> list = new ArrayList<>();
        for(TaskOrder taskOrder:taskOrders){
            MyAuditListVo myAuditListVo = new MyAuditListVo();
            BeanUtils.copyProperties(taskOrder,myAuditListVo);
            if(taskOrder.getState() == 1){
                //0未审核，1通过，2不通过，3被申诉
                myAuditListVo.setResult(0);// 待审核
            }
            if(taskOrder.getState() == 5) {
                myAuditListVo.setResult(3);// 被申诉
            }
            if(taskOrder.getResult() != null && (taskOrder.getResult() == 1 || taskOrder.getResult() == 3)){
                myAuditListVo.setResult(1);// 通过
            }
            long autoAuditTimes = taskOrder.getAutoAuditTime()!=null?taskOrder.getAutoAuditTime().getTime() - new Date().getTime():0;
            if(autoAuditTimes>0){
                myAuditListVo.setAutoAuditTimes(autoAuditTimes);
            }else{
                myAuditListVo.setAutoAuditTimes(0l);
            }
            list.add(myAuditListVo);
        }
        return Rets.success(list);
    }

    /**
    * @date: 2022/4/3 23:41 已接取任务列表
    * @param state: 订单状态 1待提交，2审核中，3已完成，4未通过，5已申诉，6已取消
    * @param page:  页码
    * @param limit:  页大小
    * @Return:
    */
    @GetMapping("/myOrderList")
    public Ret myOrder(@RequestParam(defaultValue = "0") Integer state,
                       @RequestParam(defaultValue = "1") Integer page,
                       @RequestParam(defaultValue = "10") Integer limit){
        StringBuffer sql = new StringBuffer("select * from t_task_order where 1=1 ");
        sql.append(" and create_by = "+JwtUtil.getUserId());
        if(state!=0){
            sql.append(" and state = "+state);
        }
        sql.append(" order by create_time desc");
        if(page<1) page = 1;
        int start = (page-1)*limit;
        sql.append(" LIMIT "+start+","+limit);
        List<TaskOrder> taskOrders = orderService.queryBySql(sql.toString());
        List<MyOrderListVo> orderListVos = new ArrayList<>();
        for(TaskOrder taskOrder:taskOrders){
            MyOrderListVo listVo = new MyOrderListVo();
            BeanUtils.copyProperties(taskOrder,listVo);
            long time = taskOrder.getTimeLimit()!=null?taskOrder.getTimeLimit().getTime() - new Date().getTime():0;
            if(time>0){
                listVo.setTimeLimits(time);// 截止时间秒数
            }else{
                listVo.setTimeLimits(0l);
            }
            orderListVos.add(listVo);
        }
        return Rets.success(orderListVos);
    }
    /**
     * 放弃订单
    * @param orderId 订单ID
    * @Return
    */
    @GetMapping("/waiveOrder")
    public Ret waiveOrder(Long orderId){
        if(orderId == null){
            return Rets.failure("任务ID不能为空！");
        }
        TaskOrder taskOrder = orderService.get(orderId);
        if(taskOrder == null){
            return Rets.failure("订单不存在！");
        }
        if(taskOrder.getCreateBy()!=JwtUtil.getUserId()){
            return Rets.failure("不能放弃他人的订单哦！");
        }
        taskOrder.setState(6);
        TaskOrder newtaskorder = orderService.update(taskOrder);
        HelpTask helpTask = taskService.get(taskOrder.getTaskId());
        helpTask.setLastNum(helpTask.getLastNum()+1);
        if(helpTask.getLastNum() == 1 && helpTask.getState() == 6){
            helpTask.setState(1);
        }
        HelpTask update = taskService.update(helpTask);
        if(newtaskorder!=null && update != null){
            return Rets.success();
        }
        throw new RuntimeException();
    }

    /**
     * 提交凭证
     * @param orderProofDto 订单凭证列表
     * @return
     */
    @PostMapping("/submitProof")
    public Ret submitProof(@RequestBody SubmitOrderProofDto orderProofDto){
        TaskOrder taskOrder = orderService.get(orderProofDto.getOrderId());
        if(taskOrder == null){
            return Rets.failure("订单不存在！");
        }
        if(taskOrder.getState() != 1){
            return Rets.failure("该订单不允许提交凭证！");
        }
        // 所需提交凭证
        List<SearchFilter> searchFilterList = new ArrayList<>();
        searchFilterList.add(new SearchFilter("orderId", SearchFilter.Operator.EQ,orderProofDto.getOrderId()));
        searchFilterList.add(new SearchFilter("createBy", SearchFilter.Operator.EQ,JwtUtil.getUserId()));
        List<Proof> taskProofs = proofService.queryAll(searchFilterList);
        if(orderProofDto!=null && orderProofDto.getOrderProofList().size()>0){
            List<ProofDto> orderProofList = orderProofDto.getOrderProofList();
            for(ProofDto proofDto:orderProofList){ // 上传的凭证
               for(Proof taskProof:taskProofs){
                   if(taskProof.getName().equals(proofDto.getName()) && taskProof.getType()== proofDto.getType()){
                       taskProof.setModifyBy(JwtUtil.getUserId());
                       taskProof.setModifyTime(new Date());
                       taskProof.setContent(proofDto.getContent());// 保存凭证信息
                       proofService.update(taskProof);
                       break;
                   }
               }
            }
        }
        taskOrder.setState(2);// 审核中
        taskOrder.setSubmitTime(new Date());
        Integer extraTime = getExtraTime();
        Integer autoAuditTime = auditTimeLimit+ extraTime;
        taskOrder.setAutoAuditTime(DateUtil.getAfterHourDate(autoAuditTime));
        orderService.update(taskOrder);
        return Rets.success();
    }

    /**
     * 审核订单/重新审核（被申述的订单可以复审通过）
     * @param orderId 订单编号
     * @param result 审核结果 1通过，2不通过
     * @param reason 不通过原因，不通过时必填
     * @return
     */
    @GetMapping("/audit")
    public Ret audit(Long orderId,Integer result,String reason){
        TaskOrder taskOrder = orderService.get(orderId);
        User user = userService.get(taskOrder.getCreateBy());// 接单人信息
        if(taskOrder == null){
            return Rets.failure("订单不存在！");
        }
        if(taskOrder.getIssuerId()!=JwtUtil.getUserId()){
            return Rets.failure("该订单不是您的订单哦~");
        }
        if(result == 2){
            if(StringUtil.isNullOrEmpty(reason)){
                return Rets.failure("不通过原因不能为空！");
            }
            taskOrder.setState(4);// 订单状态不通过
            taskOrder.setReason(reason); // 设置不通过原因
        }else if(result == 1){
            taskOrder.setState(3);// 已完成
            moneyInfoService.setMoneyInfo(taskOrder.getTaskId(),user.getId(),1,taskOrder.getMoney());//设置金额明细并变动用户金额
        }else {
            return Rets.failure("只有通过/不通过两个结果哦~");
        }
        taskOrder.setAuditTime(new Date());
        taskOrder.setResult(result);
        Integer extraTime = getExtraTime();
        Integer autoWaiverTime = auditFailed + extraTime;
        taskOrder.setAutoWaiverTime(DateUtil.getAfterHourDate(autoWaiverTime));
        TaskOrder update = orderService.update(taskOrder);
        if(update == null){
            throw new RuntimeException("审核失败！");
        }
        return Rets.success();
    }

    /**
     * 申述订单
     * @param orderId 订单ID
     * @param appeal 申述内容
     * @return
     */
    @GetMapping("/appeal")
    public Ret appeal(Long orderId,String appeal){
        TaskOrder taskOrder = orderService.get(orderId);
        if(taskOrder== null){
            return Rets.failure("订单不存在！");
        }
        if(taskOrder.getState()!=4){
            return Rets.failure("未通过的订单才能申述哦~");
        }
        if(StringUtil.isNullOrEmpty(appeal)){
            return Rets.failure("申述内容不能为空！");
        }
        if(taskOrder.getCreateBy()!=JwtUtil.getUserId()){
            return Rets.failure("不能申述他人的订单哦~");
        }
        taskOrder.setAppeal(appeal);
        taskOrder.setState(5); // 已申诉，申述后由平台处理
        taskOrder = orderService.update(taskOrder);
        return taskOrder == null ? Rets.failure("申述失败"):Rets.success();
    }

    /**
     * 深夜额外加时
     * @return
     */
    private Integer getExtraTime(){
        Calendar calendar = Calendar.getInstance();
        int hour = calendar.get(Calendar.HOUR_OF_DAY); // 24小时制
        Integer extraTime  = 0;
        if(hour>=22){ // 22~23点
            extraTime = 10 + 24 - hour;
        }
        if(hour>=0 && hour<10){ // 0~10点
            extraTime = 10 - hour;
        }
        return extraTime;
    }

}
